#!/usr/bin/python

import re
import sys
import bsddb
import cStringIO
import hashlib

def half_md5(string):
    return int( hashlib.md5( string ).hexdigest()[16:], 16 )

BORDERS_RE = re.compile('(complement)?\(?<?(\d+)..>?(\d+)\)?')

def parse_genes(s):
    f = cStringIO.StringIO(s)
    for line in f:
        if line.startswith('     gene            '):
            borders = line.strip().split()[1]
            yield borders

def parse_cds(s):
    f = cStringIO.StringIO(s)
    gene_started = False
    product_started = False
    borders = None
    product = None
    for line in f:
        if gene_started:
            if not line.startswith('                     '):
                if borders and product:
                    yield borders, product
                    borders, product = None, None
                    gene_started = False
                else:
                    raise Exception('Bad CDS')
            else:
                line = line.strip()
                if product_started:
                    product += ' ' + line
                    if product.endswith('"'):
                        product_started = False
                        roduct = product[:-1]
                elif line.startswith("/product"):
                    product_started = True
                    product = line.split('/product="')[1]
                    if product.endswith('"'):
                        product_started = False
                        product = product[:-1]
        elif line.startswith('     CDS             '):
            borders = line.strip().split()[1]
            gene_started = True


if __name__ == "__main__":
 
    raw_db_fname = sys.argv[1]
    gen_db_fname = sys.argv[2]

    cnt_all = 0
    cnt_genes = 0
    raw_db = bsddb.hashopen(raw_db_fname, 'r')
    gen_db = bsddb.hashopen(gen_db_fname, 'w')
    for locus, raw_desc in raw_db.iteritems():
        cnt_all += 1
        gene_borders = set(parse_genes(raw_desc))
        cds_borders = dict(parse_cds(raw_desc))
        for borders in gene_borders:
            gene_id = "%s_%s" % (locus, half_md5(borders))
            product = cds_borders.get(borders, '__NULL__')
            gen_db[gene_id] = "%s\n%s\n" % (borders, product)
            cnt_genes += 1
    raw_db.close()
    gen_db.sync()
    gen_db.close()

    print "Done! (%s/%s)" % (cnt_all, cnt_genes)

